package com.tsinkai.ettp.practice;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.Security;

import org.apache.commons.codec.binary.Hex;
import org.apache.commons.codec.digest.DigestUtils;
import org.bouncycastle.crypto.Digest;
import org.bouncycastle.crypto.digests.MD2Digest;
import org.bouncycastle.crypto.digests.MD4Digest;
import org.bouncycastle.crypto.digests.MD5Digest;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

public class MDPra {
	
	private static String src = "hello world";
	
	public static void main(String[] args) {
		jdkMD2();
		jdkMD5();
		
		bcMD2();
		bcMD4();
		bcMD5ForProvider();
		bcMD4ForProvider();
		
		ccMD2();
		ccMD5();
	}
	
	//JDK实现MD2
	public static void jdkMD2() {
		try {
			MessageDigest md = MessageDigest.getInstance("MD2");
			byte[] md2bytes = md.digest(src.getBytes());
			//字节数组输出要先转成16进制，可以借助HEX类转换
			System.out.println("JDK MD2:" + Hex.encodeHexString(md2bytes));
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
	}
	
	//JDK实现MD5
	public static void jdkMD5() {
		try {
			MessageDigest md = MessageDigest.getInstance("MD5");
			byte[] md5bytes = md.digest(src.getBytes());
			//字节数组输出要先转成16进制，可以借助HEX类转换
			System.out.println("JDK MD5:" + Hex.encodeHexString(md5bytes));
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
	}
	
	//Bouncy Castle实现MD2
	public static void bcMD2() {
		Digest digest = new MD2Digest();
		digest.update(src.getBytes(), 0, src.getBytes().length); 
		byte[] MD2Bytes = new byte[digest.getDigestSize()];
		digest.doFinal(MD2Bytes, 0);
		System.out.println("BC MD2:" + org.bouncycastle.util.encoders.Hex.toHexString(MD2Bytes));
	}
	
	//Bouncy Castle实现MD4
	public static void bcMD4() {
		Digest digest = new MD4Digest();
		digest.update(src.getBytes(), 0, src.getBytes().length);
		byte[] MD4Bytes = new byte[digest.getDigestSize()];
		digest.doFinal(MD4Bytes, 0);
		System.out.println("BC MD4:" + org.bouncycastle.util.encoders.Hex.toHexString(MD4Bytes));
	}
	//通过设置provider，使用jdk的包调用bouncyCastle的实现，MD5
	//该种方式的provider是sun，若是使用该方式调用MD4,则实现则是BC
	public static void bcMD5ForProvider() {
		
		try {
			Security.addProvider(new BouncyCastleProvider());
			MessageDigest md = MessageDigest.getInstance("MD5");
			System.err.println("JDKforProvider MD5:"+md.getProvider());
			byte[] md5bytes = md.digest(src.getBytes());
			//字节数组输出要先转成16进制，可以借助HEX类转换
			System.out.println("BC MD5ForProvider:" + Hex.encodeHexString(md5bytes));
			
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
	}
	//通过设置provider，使用jdk的包调用bouncyCastle的实现，MD4
	public static void bcMD4ForProvider() {
			
			try {
				Security.addProvider(new BouncyCastleProvider());
				MessageDigest md = MessageDigest.getInstance("MD4");
				System.err.println("JDKforProvider MD4:"+md.getProvider());
				byte[] md5bytes = md.digest(src.getBytes());
				//字节数组输出要先转成16进制，可以借助HEX类转换
				System.out.println("BC MD4ForProvider:" + Hex.encodeHexString(md5bytes));
				
			} catch (NoSuchAlgorithmException e) {
				e.printStackTrace();
			}
		}
	//Commons Codes实现MD2
	public static void ccMD2() {
		System.out.println("CC MD2:"+ DigestUtils.md2Hex(src.getBytes()));
	}
	
	//Commons Codes实现MD5
	public static void ccMD5() {
		System.out.println("CC MD5:"+ DigestUtils.md5Hex(src.getBytes()));
	}
}
